package Controllers;

import Configs.Config;
import GUIs.f_nhanvien_nguoithue_hopdong_them;
import com.db4o.ObjectSet;
import com.db4o.query.Predicate;
import com.db4o.query.Query;
import com.db4o.query.QueryComparator;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import javax.swing.JOptionPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
import models.HoaDon;
import models.HopDong;
import models.NhanVien;
import models.PhongTro;

public class HopDongController {

    private final Config conn;
    private BieuThucChinhQuy btcq;
    private MyTableFormat myFormat;

    public HopDongController(Config conn) {
        this.conn = conn;
    }

    public HopDong getWithMaHopDong(String maHopDong) {
        return this.conn.getConn().query(new Predicate<HopDong>() {
            @Override
            public boolean match(HopDong et) {
                return (et.getMSHD().equals(maHopDong));
            }
        }).next();
    }

    public String generateMaHopDong() {
        Query query = this.conn.getConn().query();
        query.constrain(HopDong.class);
        Query sortBy = query.sortBy(new QueryComparator<HopDong>() {
            @Override
            public int compare(HopDong hopDongA, HopDong hopDongB) {
                return XuLyChuoi.getNumHopDong(hopDongB.getMSHD()) - XuLyChuoi.getNumHopDong(hopDongA.getMSHD());
            }
        });
        HopDong hopDong = (HopDong) query.execute().next();
        int maxMaHopDong = XuLyChuoi.getNumHopDong(hopDong.getMSHD()) + 1;
        return XuLyChuoi.joinMaHopDong(maxMaHopDong);
    }

    public void Show(JTable tbdsHopDong, String txttim, String cmnd) {
        DefaultTableModel model = (DefaultTableModel) tbdsHopDong.getModel();
        this.myFormat = new MyTableFormat();
        SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss dd-MM-yyyy");
        if (txttim == null) {
            ObjectSet<HopDong> hopDongs = this.conn.getConn().query(new Predicate<HopDong>() {
                @Override
                public boolean match(HopDong et) {
                    return et.getNguoithue().getCMND().equals(cmnd) && !et.getIsDel();
                }
            });
            int stt = 0;
            for (HopDong hopDong : hopDongs) {
                Object[] row = {++stt, hopDong.getMSHD(), sdf.format(hopDong.getThoidiemlap()), (this.tinhTrangHoaDon(hopDong.getDshoadon())) ? "Đã đóng tiền" : "Chưa đóng tiền"};
                model.addRow(row);
            }
        } else {
            ObjectSet<HopDong> hopDongs;
            hopDongs = this.conn.getConn().query(new Predicate<HopDong>() {
                @Override
                public boolean match(HopDong et) {
                    return !et.getIsDel()
                            && et.getNguoithue().getCMND().equals(cmnd)
                            && (et.getMSHD().toLowerCase().startsWith(txttim.toLowerCase()) || et.getMSHD().toLowerCase().endsWith(txttim.toLowerCase()));
                }
            });
            int stt = 0;
            for (HopDong hopDong : hopDongs) {
                Object[] row = {++stt, hopDong.getMSHD(), sdf.format(hopDong.getThoidiemlap()), (this.tinhTrangHoaDon(hopDong.getDshoadon())) ? "Đã đóng tiền" : "Chưa đóng tiền"};
                model.addRow(row);
            }
        }
        this.myFormat.formatTable(tbdsHopDong);
    }

    public boolean Add(f_nhanvien_nguoithue_hopdong_them hopdong_them) {
        String ghiChu = hopdong_them.textareaghichu.getText().trim();
        this.btcq = new BieuThucChinhQuy(ghiChu, "[^!@#$%^&*\\{\\}\\\\'\\\"]+$");
        if (!ghiChu.isEmpty() && !this.btcq.isBoolean()) {
            JOptionPane.showMessageDialog(hopdong_them, "Ghi chú có chứa ký tự đặc biệt.", "Thông báo", JOptionPane.ERROR_MESSAGE);
            hopdong_them.textareaghichu.requestFocus();
        } else if (hopdong_them.maPhong.equals("-1")) {
            JOptionPane.showMessageDialog(hopdong_them, "Bạn chưa chọn phòng trọ trống nào.", "Thông báo", JOptionPane.ERROR_MESSAGE);
            hopdong_them.tbphongtrong.requestFocus();
        } else {
            NhanVien nhanVien = this.conn.getConn().query(new Predicate<NhanVien>() {
                @Override
                public boolean match(NhanVien nhanvien) {
                    return (nhanvien.getMSNV().equals(hopdong_them.msnv));
                }
            }).next();

            PhongTro phongTro = this.conn.getConn().query(new Predicate<PhongTro>() {
                @Override
                public boolean match(PhongTro et) {
                    return et.getMaphong().equals(hopdong_them.maPhong);
                }
            }).next();

            HopDong themmoi = new HopDong(hopdong_them.lbmahd_tt.getText(), new Date(), ghiChu, hopdong_them.dpngaysudung.getDate());
            themmoi.setNguoithue(hopdong_them.nguoiThue);
            themmoi.setPhongtro(phongTro);
            themmoi.setNhanvien(nhanVien);
            hopdong_them.nguoiThue.AddHopDong(themmoi);
            phongTro.addHopDong(themmoi);
            phongTro.setTinhtrang(false);
            nhanVien.addHopDong(themmoi);
            this.conn.getConn().store(themmoi);
            return true;
        }
        return false;
    }

    public void Edit() {

    }

    public boolean Delete(String maHopDong) {
        ObjectSet<HopDong> xoa = this.conn.getConn().query(new Predicate<HopDong>() {
            @Override
            public boolean match(HopDong et) {
                return et.getMSHD().equals(maHopDong);
            }
        });
        while (xoa.hasNext()) {
            HopDong hopDong = xoa.next();
            if (hopDong.getDshoadon().isEmpty()) {
                hopDong.getPhongtro().setTinhtrang(true);
                hopDong.getNguoithue().removeHopDong(hopDong);
                hopDong.getNhanvien().removeHopDong(hopDong);
                hopDong.getPhongtro().removeHopDong(hopDong);
                this.conn.getConn().delete(hopDong);
            } else {
                hopDong.setIsDel(true);
                this.conn.getConn().store(hopDong);
            }
        }
        return true;
    }

    public boolean tinhTrangHoaDon(List<HoaDon> dsHoaDon) {
        try {
            int numHD = dsHoaDon.size();
            if (numHD > 0) {
                Calendar cal = Calendar.getInstance();
                int year = cal.get(Calendar.YEAR);
                int month = cal.get(Calendar.MONTH) + 1;
                return dsHoaDon.stream().anyMatch((hoaDon) -> (hoaDon.getNam() == year && (hoaDon.getTuthang() <= month && hoaDon.getDenthang() >= month)));
            }
        } catch (Exception ex) {

        }
        return false;
    }
}
